import { isArray } from '@/utils/is';
import { dictList } from '@/api/sys';
import type { IDictList, IDictItem } from '@/api/sys/model/indexModel';
import localDicts from './localDicts';

type localKey = keyof typeof localDicts;
export type localDicts = {
  [key in localKey]: IDictItem[];
};
class Dictionary {
  private dictAll!: Map<localKey | string, IDictItem[]>;
  constructor() {
    this.dictAll = new Map();
    this.init();
  }

  /**
   * @description 初始化本地字典
   * @date 13/07/2022
   * @private
   * @memberof Dictionary
   */
  private init() {
    for (const key in localDicts) {
      if (key) this.add(key, localDicts[key]);
    }
  }

  /** 添加 */
  public add(key: string, val: IDictItem[]): boolean {
    this.dictAll.set(key, val);
    return true;
  }

  /** 访问本地单个字段 */
  public getLocal(key: string): IDictItem[] {
    return this.dictAll.get(key) || [];
  }

  /** 访问本地多个字段 */
  public getLocalMulti(key: string[]): localDicts {
    const obj: any = {};
    key.forEach((v) => this.hasKey(v) && (obj[v] = this.dictAll.get(v) as IDictItem[]));
    return obj;
  }

  /** 获取单个(服务端) */
  public async get(key: string): Promise<IDictItem[] | []> {
    if (!this.hasKey(key)) {
      const res = await this.queryServerDict(key);
      if (!res[key]) return [];
      this.add(key, res[key]);
    }
    const val = this.dictAll.get(key);
    return val ? val : [];
  }

  /** 获取多个(服务端) */
  public async getMulti(key: string[]): Promise<IDictList> {
    const obj: IDictList = {};
    const noneKeys: string[] = [];
    key.forEach((v) =>
      this.hasKey(v) ? (obj[v] = this.dictAll.get(v) as IDictItem[]) : noneKeys.push(v),
    );
    if (noneKeys.length > 0) {
      const res = await this.queryServerDict(noneKeys);
      for (const k in res) {
        const val = res[k];
        obj[k] = val;
        this.add(k, val);
      }
    }
    return obj;
  }

  /** 查找 */
  public hasKey(key: string): boolean {
    return this.dictAll.has(key);
  }

  /** 删除 */
  public remove(key: string): boolean {
    return this.hasKey(key) && this.dictAll.delete(key);
  }

  /** 获取字典大小 */
  public size(): number {
    return this.dictAll.size;
  }

  /** 是否为空 */
  public isEmpty(): boolean {
    return this.size() === 0;
  }

  /** 获取键数组 */
  public keys(): string[] {
    return Array.from(this.dictAll.keys());
  }

  /** 获取键值数组 */
  public keyValues() {
    return Array.from(this.dictAll.entries());
  }

  private async queryServerDict(key: string[] | string) {
    const dictTypes = isArray(key) ? key.join(',') : key;
    const r = await dictList(dictTypes);
    return r;
  }
}

const dictionary = new Dictionary();
export default dictionary;
